package edu.sysu.demo.petstore.dog.web.rest;

import static org.assertj.core.api.Assertions.assertThat;

import edu.sysu.demo.petstore.dog.RandomStringBuilder;
import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;

@Slf4j
public class LoginControllerIT {

  private TestRestTemplate restTemplate;

  private RandomStringBuilder rand;

  private String username;
  private String password;

  @Before
  public void setUp() {
    SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
    requestFactory.setOutputStreaming(false);

    restTemplate = new TestRestTemplate(
        new RestTemplateBuilder().requestFactory(() -> requestFactory));

    rand = RandomStringBuilder.newBuilder()
        .useDigit()
        .useUpperCase()
        .useLowerCase()
        .useSymbol();
    username = rand.build(10);
    password = rand.build(10);

    RegisterForm registerForm = new RegisterForm(username, password);

    ResponseEntity<RegisterResult> response = restTemplate.postForEntity(
        Location.REGISTER.getUrl(),
        registerForm,
        RegisterResult.class);

    assertThat(response).isNotNull();
    assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
    assertThat(response.getBody()).isNotNull();
    assertThat(response.getBody().getUsername()).isEqualTo(username);

  }

  @Test
  public void loginSuccess() {
    LoginForm loginForm = new LoginForm(username, password);
    ResponseEntity<String> entity = restTemplate.postForEntity(
        Location.LOGIN.getUrl(), loginForm, String.class);

    assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
    log.info("Login Token : {}", entity.getBody());
  }

  @Test
  public void loginInvalidPassword() {
    final String invalidPassword = rand.build(33, 50);
    LoginForm loginForm = new LoginForm(username, invalidPassword);
    ResponseEntity<String> entity = restTemplate.postForEntity(
        Location.LOGIN.getUrl(), loginForm, String.class);
    log.info("{}", entity.getBody());

    assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
  }

  @Test
  public void loginInvalidUser() {
    final String invalidUser = rand.build(15, 50);
    LoginForm loginForm = new LoginForm(invalidUser, invalidUser);
    ResponseEntity<String> entity = restTemplate.postForEntity(
        Location.LOGIN.getUrl(), loginForm, String.class);
    log.info("{}", entity.getBody());
    assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
  }
}